package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.*;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.query.QuestionAdminPageQuery;
import com.tianji.learning.query.QuestionPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author lcm
 * @since 2023-07-26
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    private final UserClient userClient;
//    private final IInteractionReplyService replyService;
    private final InteractionReplyMapper replyMapper;
    private final CourseClient courseClient;
    private final SearchClient searchClient;
    private final CatalogueClient catalogueClient;
    private final CategoryCache categoryCache;
    private final RabbitMqHelper mqHelper;



    @Override
    public void addQuestion(QuestionFormDTO questionFormDTO) {
        //1.获取用户id
        Long userId = UserContext.getUser();
        //2.拷贝问题po
        InteractionQuestion question = BeanUtils.copyBean(questionFormDTO, InteractionQuestion.class);
        question.setUserId(userId);
        //3.添加至数据库
        save(question);
        //4.发送MQ消息至积分服务
        mqHelper.send(
                MqConstants.Exchange.LEARNING_EXCHANGE,
                MqConstants.Key.WRITE_REPLY,
                userId
        );
        log.info("用户：{}向积分服务发送，课程小节学习一小节",userId);
    }

    @Override
    public void updateQuestion(Long id,QuestionFormDTO questionFormDTO) {
        //1.获取用户id
        Long userId = UserContext.getUser();
        //2.拷贝问题po
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .one();
        if(question == null){
            throw new BadRequestException("修改问题失败!问题不存在");
        }
        question.setTitle(questionFormDTO.getTitle());
        question.setDescription(questionFormDTO.getDescription());
        question.setAnonymity(questionFormDTO.getAnonymity());
        question.setUserId(userId);
        //3.添加至数据库
        updateById(question);
    }

    @Override
    public PageDTO<QuestionVO> pageQuery(QuestionPageQuery questionPageQuery) {
        //1.获取提问者用户id
        Long userId = UserContext.getUser();
        //2.校验课程id和小节id不为空
        Long courseId=questionPageQuery.getCourseId();
        Long sectionId = questionPageQuery.getSectionId();
        if( courseId == null && sectionId == null){
            throw new BadRequestException("课程id和小节id不能都为空");
        }
        //3.分页查询条件
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class,info ->!info.getProperty().equals("description"))
                .eq(courseId != null,InteractionQuestion::getCourseId,courseId)
                .eq(sectionId!=null,InteractionQuestion::getSectionId,sectionId)
                .eq(InteractionQuestion::getHidden,false)
                .eq(questionPageQuery.getOnlyMine(), InteractionQuestion::getUserId, userId)
                .page(questionPageQuery.toMpPageDefaultSortByCreateTimeDesc());
        //健壮性处理
        List<InteractionQuestion> records = page.getRecords();
        if(CollUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }


        //获取用户id集合、最近一次问答id集合
        Set<Long> userList = records.stream()
                .filter(r -> !r.getAnonymity() && ObjectUtils.isNotNull(r.getUserId()))
                .map(InteractionQuestion::getUserId)
                .collect(Collectors.toSet());

        Set<Long> answerList = records.stream()
                .map(InteractionQuestion::getLatestAnswerId)
                .filter(ObjectUtils::isNotNull)
                .collect(Collectors.toSet());


        //查询最近的一次问答
        Map<Long,InteractionReply> replyMap = new HashMap<>(answerList.size());
        if(CollUtils.isNotEmpty(answerList)){
            List<InteractionReply> replies = replyMapper.selectBatchIds(answerList);
            for (InteractionReply reply : replies) {
                replyMap.put(reply.getId(),reply);
                if(!reply.getAnonymity()){
                    userList.add(reply.getUserId());
                }
            }
//            replyMap = replies.stream().collect(Collectors.toMap(InteractionReply::getId, Function.identity()));
        }


        //根据id查询用户信息
        Map<Long, UserDTO> userMap = new HashMap<>(userList.size());
        if(CollUtils.isNotEmpty(userList)){
            List<UserDTO> userDTOList = userClient.queryUserByIds(userList);
            userMap = userDTOList.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
        }

        //封装vo
        List<QuestionVO> voList = new ArrayList<>(records.size());

        for (InteractionQuestion question : records) {
            QuestionVO questionVO = BeanUtils.copyBean(question, QuestionVO.class);

            if(!question.getAnonymity()){
                UserDTO userDTO = userMap.get(userId);
                if(userDTO!=null){
                    questionVO.setUserIcon(userDTO.getIcon());
                    questionVO.setUserName(userDTO.getName());
                }
            }

            InteractionReply reply = replyMap.get(question.getLatestAnswerId());
            if(reply!=null){
                questionVO.setLatestReplyContent(reply.getContent());
                if(!reply.getAnonymity()){// 匿名用户直接忽略
                    UserDTO user = userMap.get(reply.getUserId());
                    questionVO.setLatestReplyUser(user.getName());
                }
            }

            voList.add(questionVO);

        }

        return PageDTO.of(page,voList);
    }

    @Override
    public QuestionVO questionDetails(Long id) {
        //1.查询对应问题
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .eq(InteractionQuestion::getHidden, false)
                .one();
        //2.数据封装
        QuestionVO questionVO = BeanUtils.copyBean(question, QuestionVO.class);
        UserDTO userDTO = userClient.queryUserById(questionVO.getUserId());
        questionVO.setUserIcon(userDTO.getIcon());
        questionVO.setUserName(userDTO.getName());
        return questionVO;
    }

    @Override
    public void deleteQuestion(Long id) {
        //1.查询问题对象
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .one();
        if(question==null){
            throw new BadRequestException("问题不存在！");
        }
        //2.删除
        removeById(id);
    }

    @Override
    public PageDTO<QuestionAdminVO> adminPageQuery(QuestionAdminPageQuery questionPageQuery) {
        //1.处理课程名称，得到课程id
        List<Long> cIds = new ArrayList<>();
        if(StringUtils.isNotEmpty(questionPageQuery.getCourseName())){
            cIds = searchClient.queryCoursesIdByName(questionPageQuery.getCourseName());
        }
        if(CollUtils.isEmpty(cIds)){
            return PageDTO.empty(0L,0L);
        }
        //2.分页查询
        Integer status = questionPageQuery.getStatus();
        LocalDateTime begin = questionPageQuery.getBeginTime();
        LocalDateTime end = questionPageQuery.getEndTime();

        Page<InteractionQuestion> page = lambdaQuery()
                .in(InteractionQuestion::getCourseId, cIds)
                .ge(begin!=null,InteractionQuestion::getUpdateTime, begin)
                .le(end!=null,InteractionQuestion::getUpdateTime, end)
                .eq(status!=null,InteractionQuestion::getStatus, status)
                .page(questionPageQuery.toMpPageDefaultSortByCreateTimeDesc());

        List<InteractionQuestion> records = page.getRecords();

        if(CollUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }
        //3.准备VO需要的数据：用户数据、课程数据、章节数据、分类数据
        Set<Long> uIds = records.stream().map(InteractionQuestion::getUserId).collect(Collectors.toSet());
        Set<Long> courseIds = records.stream().map(InteractionQuestion::getCourseId).collect(Collectors.toSet());
        Set<Long> CaTaId = records.stream()
                .flatMap(q -> Stream.of(q.getChapterId(), q.getSectionId()))
                .collect(Collectors.toSet());

        //3.1 用户数据
        List<UserDTO> users = userClient.queryUserByIds(uIds);
        Map<Long, UserDTO> userMap = new HashMap<>(users.size());
        if (CollUtils.isNotEmpty(users)){
            userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
        }

        //3.2 课程数据
        List<CourseSimpleInfoDTO> courses= courseClient.getSimpleInfoList(courseIds);
        Map<Long, CourseSimpleInfoDTO> courseMap = new HashMap<>(courses.size());
        if(CollUtils.isEmpty(courses)){
            courseMap = courses.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, Function.identity()));
        }

        //3.3 章节数据
        List<CataSimpleInfoDTO> caTas = catalogueClient.batchQueryCatalogue(CaTaId);
        Map<Long, String> caTasMap = new HashMap<>(caTas.size());
        if(CollUtils.isNotEmpty(caTas)){
            caTasMap = caTas.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId,CataSimpleInfoDTO::getName));
        }

        //4.封装VO

        List<QuestionAdminVO> voList=new ArrayList<>(records.size());
        for (InteractionQuestion question : records) {
            QuestionAdminVO vo = BeanUtils.copyBean(question, QuestionAdminVO.class);
            voList.add(vo);

            UserDTO user = userMap.get(question.getUserId());
            if(user != null){
                vo.setUserName(user.getName());
            }

            CourseSimpleInfoDTO cInfo = courseMap.get(question.getCourseId());
            if (cInfo != null) {
                vo.setCourseName(cInfo.getName());
                vo.setCategoryName(categoryCache.getCategoryNames(cInfo.getCategoryIds()));
            }

            vo.setChapterName(caTasMap.getOrDefault(question.getChapterId(),""));
            vo.setSectionName(caTasMap.getOrDefault(question.getSectionId(),""));

        }


        return PageDTO.of(page,voList);
    }

    @Override
    public QuestionAdminVO questionAdminDetails(Long id) {
        //1.查询问题
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .one();
        //2.基础属性拷贝
        QuestionAdminVO questionAdminVO = BeanUtils.copyBean(question, QuestionAdminVO.class);

        //3.查询属性数据
        //3.1用户信息
        Long userId = question.getUserId();
        UserDTO user = userClient.queryUserById(userId);
        if(user != null){
            questionAdminVO.setUserName(user.getName());
        }
        //3.2课程信息
        Long courseId = question.getCourseId();
        CourseFullInfoDTO course = courseClient.getCourseInfoById(courseId, false, false);
        if(course!=null){
            questionAdminVO.setCourseName(course.getName());
            questionAdminVO.setCategoryName(categoryCache.getCategoryNames(course.getCategoryIds()));
        }
        //3.3章节信息
        Long chapterId = question.getChapterId();
        Long sectionId = question.getSectionId();
        List<CataSimpleInfoDTO> caTa = catalogueClient.batchQueryCatalogue(List.of(chapterId, sectionId));
        Map<Long, String> caTasMap = new HashMap<>(caTa.size());
        if(CollUtils.isNotEmpty(caTa)){
            caTasMap = caTa.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId,CataSimpleInfoDTO::getName));
        }
        questionAdminVO.setChapterName(caTasMap.getOrDefault(question.getChapterId(),""));
        questionAdminVO.setSectionName(caTasMap.getOrDefault(question.getSectionId(),""));

        return questionAdminVO;
    }

    @Override
    public void hiddenOrShowQuestion(Long id, Boolean hidden) {
        //1.获取问题对象
        InteractionQuestion question = lambdaQuery()
                .eq(InteractionQuestion::getId, id)
                .one();

        if(question == null){
            throw new BadRequestException("问题不存在");
        }

        question.setHidden(hidden);
        //2.更新
        updateById(question);
    }
}
